package admin

import (
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"mojieshi/define"
	"mojieshi/models"
	"net/http"
	"strconv"
	"time"
)

// 菜单列表
func MenuList(c *gin.Context) {
	jsonData, _ := strconv.Atoi(c.Query("id"))
	jsonb, _ := strconv.Atoi(c.Query("bid"))
	var list []models.MMenu
	var count int64
	tx := models.DB.Model(new(models.MMenu))
	if jsonData > 0 {
		tx = tx.Where("id=?", jsonData)
	}
	if jsonb > 0 {
		tx = tx.Where("hidden=?", 1)
	}
	tx = tx.Count(&count).Order("sort asc,id").Find(&list)
	if tx.Error != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 10000,
			"msg":  tx.Error,
		})
		return
	}
	var dataList []MenuAddData
	if count > 0 {
		for _, v := range list {
			var TranslateList []TranslateData
			err := models.DB.Model(new(models.MTranslate)).Where("as_id=? AND as_from=?", v.ID, "m_menu").Find(&TranslateList).Error
			if err != nil {
				define.Response.ResultFail(c, 10001, err.Error(), "")
				return
			}
			dataList = append(dataList, MenuAddData{
				ID:       v.ID,
				Name:     v.Name,
				ParentId: v.ParentId,
				Type:     v.Type,
				Title:    v.Title,
				Path:     v.Path,
				NameEn:   TranslateList,
				Hidden:   v.Hidden,
			})
		}
	} else {
		list = nil
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"code":    0,
		"data": map[string]interface{}{
			"list":  dataList,
			"count": count,
		},
	})
}

// 首页菜单列表
func MenuListIndex(c *gin.Context) {
	//获取用户
	userId, _ := strconv.Atoi(c.GetHeader("userId"))
	//查询用户信息
	var userData models.MAdminUser
	err := models.DB.Model(new(models.MAdminUser)).Where("id=?", userId).First(&userData).Error
	if err != nil {
		define.Response.ResultFail(c, 10001, err.Error(), "")
		return
	}
	var list []models.MMenu
	if userData.GroupId == 0 {
		err = models.DB.Model(new(models.MMenu)).Where("hidden=?", 1).Find(&list).Error
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 10000,
				"msg":  err.Error(),
			})
			return
		}
	} else {
		//获取当前等级的权限
		var roltList []models.MRolt
		err = models.DB.Model(new(models.MRolt)).Where("role_id=?", userData.GroupId).Find(&roltList).Error
		if err != nil {
			define.Response.ResultFail(c, 10002, err.Error(), "")
			return
		}
		//循环获取权限菜单
		for _, v := range roltList {
			var data models.MMenu
			err = models.DB.Model(new(models.MMenu)).Where("hidden=? AND id=?", 1, v.MenuId).First(&data).Error
			if err != nil {
				c.JSON(http.StatusOK, gin.H{
					"code": 10000,
					"msg":  err.Error(),
				})
				return
			}
			list = append(list, data)
		}
	}

	if len(list) == 0 {
		list = nil
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"code":    0,
		"data":    list,
	})
}

type TranslateData struct {
	Name      string `json:"name"`
	Languages string `json:"languages"`                         //语种
	AsId      int    `gorm:"type:int(10);" json:"as_id"`        //关联id
	AsFrom    string `gorm:"type:varchar(255);" json:"as_from"` //关联表
	Remarks   string `gorm:"type:varchar(255);" json:"remarks"` //备注翻译
}
type MenuAddData struct {
	ID       int             `gorm:"type:int(10); primaryKey" json:"id"`
	Name     string          `gorm:"type:varchar(255);" json:"name"`     //名称
	ParentId int             `gorm:"type:int(10);" json:"parent_id"`     //父级id
	Hidden   int             `gorm:"type:int(10);" json:"hidden"`        //是否显示 1:显示 2:隐藏
	Type     int             `gorm:"type:int(10);" json:"type"`          //菜单类型 1:目录 2菜单
	Path     string          `gorm:"type:varchar(255);" json:"path"`     //菜单路径--标识
	Icon     string          `gorm:"type:varchar(255);" json:"icon"`     //图标
	Title    string          `gorm:"type:varchar(255);" json:"title"`    //菜单描述
	TitleEn  string          `gorm:"type:varchar(255);" json:"title_en"` //英文菜单描述
	Sort     int             `gorm:"type:int(10);" json:"sort"`          //菜单排序
	NameEn   []TranslateData `json:"name_en"`                            //语种列表
}

// 菜单新增or编辑
func MenuAdd(c *gin.Context) {
	//接收传值
	var jsonData MenuAddData
	err := c.ShouldBindJSON(&jsonData)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 10000,
			"msg":  err,
		})
		return
	}
	var menuId = 0
	tx := models.DB.Begin() //开启事务
	//判断新增还是修改
	if jsonData.ID > 0 {
		//编辑
		var data = map[string]interface{}{
			"name":      jsonData.Name,
			"parent_id": jsonData.ParentId,
			"hidden":    jsonData.Hidden,
			"type":      jsonData.Type,
			"path":      jsonData.Path,
			"icon":      jsonData.Icon,
			"title":     jsonData.Title,
		}
		err = tx.Model(new(models.MMenu)).Where("id=?", jsonData.ID).Updates(&data).Error
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 10002,
				"msg":  err.Error(),
			})
			tx.Rollback()
			return
		}
		//查询是否存在原有数据,有就删除
		err = TranslateDel(tx, jsonData.ID, "m_menu")
		if err != nil {
			define.Response.ResultFail(c, 20001, err.Error(), "")
			tx.Rollback()
			return
		}
		//批量插入数据
		var listData []models.MTranslate
		for _, v := range jsonData.NameEn {
			listData = append(listData, models.MTranslate{
				AsId:      jsonData.ID,
				CreatedAt: int(time.Now().Unix()),
				AsFrom:    "m_menu",
				Name:      v.Name,
				Languages: v.Languages,
				Remarks:   v.Remarks,
			})
		}
		//批量插入翻译
		err = tx.Model(new(models.MTranslate)).Create(&listData).Error
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 10002,
				"msg":  err.Error(),
			})
			tx.Rollback()
			return
		}
		//写入日志
		userId, _ := strconv.Atoi(c.GetHeader("userId")) //将字符串转为int
		userName, bid := models.UserName(userId)
		logData := "管理员：" + userName + "，修改了菜单:" + jsonData.Name + "的数据"
		models.LogAdd(2, "修改菜单", userId, logData, bid, 38)
	} else {
		//新增
		var data models.MMenu
		data.Name = jsonData.Name
		data.ParentId = jsonData.ParentId
		data.Hidden = jsonData.Hidden
		data.Type = jsonData.Type
		data.Path = jsonData.Path
		data.Icon = jsonData.Icon
		data.Title = jsonData.Title
		data.CreatedAt = int(time.Now().Unix())
		//新增
		result := tx.Model(new(models.MMenu)).Create(&data)
		if result.Error != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 10001,
				"msg":  result.Error,
			})
			tx.Rollback()
			return
		}
		menuId = data.ID
		//批量插入数据
		var listData []models.MTranslate
		for _, v := range jsonData.NameEn {
			listData = append(listData, models.MTranslate{
				AsId:      data.ID,
				CreatedAt: int(time.Now().Unix()),
				AsFrom:    "m_menu",
				Name:      v.Name,
				Languages: v.Languages,
				Remarks:   v.Remarks,
			})
		}
		//批量插入翻译
		err = tx.Model(new(models.MTranslate)).Create(&listData).Error
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 10002,
				"msg":  err.Error(),
			})
			tx.Rollback()
			return
		}

		//写入日志
		userId, _ := strconv.Atoi(c.GetHeader("userId")) //将字符串转为int
		userName, bid := models.UserName(userId)
		logData := "管理员：" + userName + "，新增了一个菜单:" + jsonData.Name
		models.LogAdd(2, "新增菜单", userId, logData, bid, 38)
	}
	tx.Commit() //事务结束
	if jsonData.ID < 1 {
		err = models.DB.Model(new(models.MMenu)).Where("id=?", menuId).Update("sort", menuId).Error
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 10002,
				"msg":  err,
			})
			return
		}
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"code":    0,
		"msg":     "成功",
	})
}

// 删除菜单
func MenuDel(c *gin.Context) {
	//获取管理员id
	var jsonData models.MMenu
	err := c.ShouldBindJSON(&jsonData)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 10000,
			"msg":  err,
		})
		return
	}
	var data models.MMenu
	models.DB.Model(new(models.MMenu)).Where("id=?", jsonData.ID).First(&data)
	tx := models.DB.Begin()
	//查询是否存在原有数据,有就删除
	err = TranslateDel(tx, jsonData.ID, "m_menu")
	if err != nil {
		define.Response.ResultFail(c, 20001, err.Error(), "")
		tx.Rollback()
		return
	}
	//删除
	err = tx.Delete(&models.MMenu{}, jsonData.ID).Error
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 10004,
			"msg":  err.Error(),
		})
		tx.Rollback()
		return
	}
	tx.Commit()
	//写入日志
	userId, err := strconv.Atoi(c.GetHeader("userId")) //将字符串转为int
	userName, bid := models.UserName(userId)
	logData := "管理员：" + userName + "，删除了一个菜单:" + data.Name
	models.LogAdd(4, "删除菜单", userId, logData, bid, 38)
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"code":    0,
		"msg":     "成功！",
	})
}

// 菜单排序
func MenuSort(c *gin.Context) {
	//接收id
	var jsonData models.MMenu
	err := c.ShouldBindJSON(&jsonData)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 10000,
			"msg":  err,
		})
		return
	}
	var data models.MMenu
	models.DB.Model(new(models.MMenu)).Where("id=?", jsonData.ID).First(&data)
	//修改
	err = models.DB.Model(new(models.MMenu)).Where("id=?", jsonData.ID).Update("sort", jsonData.Sort).Error
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 10002,
			"msg":  err.Error(),
		})
		return
	}
	//写入日志
	userId, err := strconv.Atoi(c.GetHeader("userId")) //将字符串转为int
	userName, bid := models.UserName(userId)
	logData := "管理员：" + userName + "，修改了:" + data.Name + "的排序"
	models.LogAdd(5, "修改菜单排序", userId, logData, bid, 38)
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"code":    0,
		"msg":     "成功！",
	})
}

// 查询是否存在原有数据有就删除
func TranslateDel(tx *gorm.DB, asid int, asfrom string) error {
	var tranList []models.MTranslate
	var count int64
	err := models.DB.Model(new(models.MTranslate)).Where("as_id=? AND as_from=?", asid, asfrom).Count(&count).Find(&tranList).Error
	if err != nil {
		return err
	}
	//判断是否有数据
	if count > 0 {
		err = tx.Where("as_id=? AND as_from=?", asid, asfrom).Delete(models.MTranslate{}).Error
		if err != nil {
			return err
		}
	}
	return nil
}
